﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using APICommon;
using DataProvider;

namespace DataBuilder
{
    /// <summary>
    /// 
    /// </summary>
    public class Builder
    {
        static List<SageMethod> _NewMethods = new List<SageMethod>();
        static List<string> _DiffMethods = new List<string>();
        public static void Build(string directory, Action<Result> resultAction, Action<Progress> progressAction)
        {
            List<SageField> oldFields = new List<SageField>();
            List<SageField> oldProperties = new List<SageField>();
            List<SageMethod> oldMethods = new List<SageMethod>();
            IEnumerable<string> files = System.IO.Directory.GetFiles(directory, "*.dll").Where(s=>!(s.Contains(".Test.") || s.Contains(".FitTest.") || s.Contains(".UnitTest")));
            //int count = 1;
            //while (count > 0)
            //{
            //    using (var db = new APIDBContext())
            //    {
            //        db.Configuration.AutoDetectChangesEnabled = false;
            //        count = db.Fields.RemoveRange(db.Fields.Take(1000)).Count();
            //        count += db.Methods.RemoveRange(db.Methods.Take(1000)).Count();
            //        db.SaveChanges();
            //    }
            //}
            foreach (string file in files)
            {
                var result =  Process(file, oldFields, oldProperties, oldMethods, progressAction);

                if (resultAction != null)
                {
                    resultAction(result);
                }
            }
        }

        //private static void ProcessDifferences()
        //{
        //    foreach (SageMethod oldMethod in _OldMethods)
        //    {
        //        SageMethod newMethod = _NewMethods.FirstOrDefault(s => s.MethodIdentity == oldMethod.MethodIdentity);
        //        if (oldMethod.ToString() != newMethod.ToString())
        //        {
        //            System.Diagnostics.Debugger.Break();
        //        }
        //    }
        //}

        private static Result Process(string file, List<SageField> fields, List<SageField> properties, List<SageMethod> methods, Action<Progress> progressAction)
        {
            Result result = new Result();
            try
            {
                //AppDomain myDomain = AppDomain.CreateDomain("Temporary");
                ////Create the loader (a proxy).
                //var assemblyLoader = (AssemblyProcessor)myDomain.CreateInstanceAndUnwrap(typeof(AssemblyProcessor).Assembly.FullName, typeof(AssemblyProcessor).FullName);
                ////Load an assembly in the LoadFrom context. Note that the Load context will
                ////not work unless you correctly set the AppDomain base-dir and private-bin-paths.

                var assemblyLoader = new AssemblyProcessor();
                result = assemblyLoader.Process(file, progressAction);

                //Finally unload the AppDomain.
                //AppDomain.Unload(myDomain);
            }
            catch(Exception ex)
            {
                result.HasErrors = true;
                result.Errors.Add(ex.Message);
                System.Diagnostics.Debug.WriteLine(string.Format("Exception {0}", ex.Message));
            }

            return result;
        }
    }
 
    static class Extensions
    {
        public static bool IsOverriding(this MethodInfo methodInfo)
        {
            if (methodInfo == null) throw new ArgumentNullException("methodInfo");
            return methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;
        }
    }
}
